package com.loong.android.tools;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;

import com.loong.android.utils.ContextUtils;
import com.loong.android.utils.DrawableUtils;

/**
 * 提示对话框
 */
public class LonAlertDialog {
    private final androidx.appcompat.app.AlertDialog.Builder mBuilder;

    //按钮id-确认按钮
    public final static int BUTTON_OK = androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE;
    //按钮id-取消按钮
    public final static int BUTTON_CANCEL = androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE;
    //按钮id-中立按钮
    public final static int BUTTON_CENTER = androidx.appcompat.app.AlertDialog.BUTTON_NEUTRAL;

    public LonAlertDialog(Context context) {
        mBuilder = new androidx.appcompat.app.AlertDialog.Builder(context);
    }

    /**
     * 获取操作的androidx.appcompat.app.AlertDialog.Builder对象
     */
    public androidx.appcompat.app.AlertDialog.Builder getBuilder() {
        return mBuilder;
    }

    /**
     * 创建提示对话框
     *
     * @param context 上下文，若不传入则自动获取当前窗口的上下文对象传入
     */
    public static LonAlertDialog build(Context context) {
        return new LonAlertDialog(context);
    }

    /**
     * 创建提示对话框，自动获取所在窗口的上下文传入
     */
    public static LonAlertDialog build() {
        return build(ContextUtils.getActivity());
    }

    /**
     * 设置对话框的图标
     *
     * @param resId 图标资源id
     */
    public LonAlertDialog setIcon(int resId) {
        mBuilder.setIcon(resId);
        return this;
    }

    /**
     * 设置对话框的图标
     *
     * @param icon 位图数据
     */
    public LonAlertDialog setIcon(Bitmap icon) {
        mBuilder.setIcon(DrawableUtils.from(mBuilder.getContext(), icon));
        return this;
    }

    /**
     * 设置对话框的图标
     *
     * @param filePath 文件路径
     */
    public LonAlertDialog setIcon(String filePath) {
        mBuilder.setIcon(DrawableUtils.from(mBuilder.getContext(), filePath));
        return this;
    }

    /**
     * 设置对话框的图标
     *
     * @param bytes 图标字节数据的数组
     */
    public LonAlertDialog setIcon(byte[] bytes) {
        mBuilder.setIcon(DrawableUtils.from(mBuilder.getContext(), bytes));
        return this;
    }

    /**
     * 设置可否取消显示对话框
     *
     * @param cancelable 为true表示可以取消，否则不能取消
     */
    public LonAlertDialog setCancelable(boolean cancelable) {
        mBuilder.setCancelable(cancelable);
        return this;
    }

    /**
     * 设置对话框显示的信息
     *
     * @param message 信息内容
     */
    public LonAlertDialog setMessage(String message) {
        mBuilder.setMessage(message);
        return this;
    }

    /**
     * 设置对话框显示的标题
     *
     * @param title 标题内容
     */
    public LonAlertDialog setTitle(String title) {
        mBuilder.setTitle(title);
        return this;
    }

    /**
     * 设置对话框的自定义视图
     *
     * @param layoutResId 布局资源id
     */
    public LonAlertDialog setView(int layoutResId) {
        mBuilder.setView(layoutResId);
        return this;
    }

    /**
     * 设置对话框的自定义视图
     *
     * @param view 视图对象
     */
    public LonAlertDialog setView(View view) {
        mBuilder.setView(view);
        return this;
    }

    /**
     * 设置对话框标题区的自定义视图
     *
     * @param view 视图对象
     */
    public LonAlertDialog setTitleView(View view) {
        mBuilder.setCustomTitle(view);
        return this;
    }

    /**
     * 设置对话框的列表项数组和单击事件
     *
     * @param items         列表数据
     * @param dialogCallback 单击事件回调，触发onItemClick事件
     */
    public LonAlertDialog setItems(String[] items, final DialogCallback dialogCallback) {
        mBuilder.setItems(items,
                (dialog, which) -> {
                    if (dialogCallback != null) dialogCallback.onItemClick(which);
                });
        return this;
    }

    /**
     * 设置对话框的单选列表数据、选中项和单击事件回调
     *
     * @param items          列表数据
     * @param checkItemIndex 选中项索引
     * @param dialogCallback  单击事件回调，触发onItemClick事件
     */
    public LonAlertDialog setSingleChoiceItems(String[] items, int checkItemIndex, DialogCallback dialogCallback) {
        mBuilder.setSingleChoiceItems(items, checkItemIndex,
                (dialog, which) -> {
                    if (dialogCallback != null) dialogCallback.onItemClick(which);
                });
        return this;
    }

    /**
     * 设置对话框的多选列表数据、选中项数组和选中事件回调
     *
     * @param items         列表数据
     * @param checkedItems  选中项数组，选择的项目为true, 未选中的位false。比如列表有三个项目["1", "2", "3"],
     *                      要选中"2", 选中项数组置为: [false, true, false]
     * @param dialogCallback 选中事件回调，触发onMultiItemCheck事件
     */
    public LonAlertDialog setMultiChoiceItems(String[] items, boolean[] checkedItems, DialogCallback dialogCallback) {
        mBuilder.setMultiChoiceItems(items, checkedItems,
                (dialog, which, isChecked) -> {
                    if (dialogCallback != null) dialogCallback.onMultiItemCheck(which, isChecked);
                });
        return this;
    }

    /**
     * 设置确认按钮的图标
     *
     * @param icon 图标的位图数据
     */
    public LonAlertDialog setOkButtonIcon(Bitmap icon) {
        mBuilder.setPositiveButtonIcon(DrawableUtils.from(mBuilder.getContext(), icon));
        return this;
    }

    /**
     * 设置确认按钮的图标
     *
     * @param filePath 图标的文件路径
     */
    public LonAlertDialog setOkButtonIcon(String filePath) {
        mBuilder.setPositiveButtonIcon(DrawableUtils.from(mBuilder.getContext(), filePath));
        return this;
    }
    
    /**
     * 设置确认按钮的图标
     *
     * @param bytes 图标字节数据的数组
     */
    public LonAlertDialog setOkButtonIcon(byte[] bytes) {
        mBuilder.setPositiveButtonIcon(DrawableUtils.from(mBuilder.getContext(), bytes));
        return this;
    }

    /**
     * 设置中立按钮的图标
     *
     * @param icon 图标的位图数据
     */
    public LonAlertDialog setCenterButtonIcon(Bitmap icon) {
        mBuilder.setNeutralButtonIcon(DrawableUtils.from(mBuilder.getContext(), icon));
        return this;
    }

    /**
     * 设置中立按钮的图标
     *
     * @param filePath 图标的文件路径
     */
    public LonAlertDialog setCenterButtonIcon(String filePath) {
        mBuilder.setNeutralButtonIcon(DrawableUtils.from(mBuilder.getContext(), filePath));
        return this;
    }

    /**
     * 设置中立按钮的图标
     *
     * @param bytes 图标字节数据的数组
     */
    public LonAlertDialog setCenterButtonIcon(byte[] bytes) {
        mBuilder.setNeutralButtonIcon(DrawableUtils.from(mBuilder.getContext(), bytes));
        return this;
    }

    /**
     * 设置取消按钮的图标
     *
     * @param icon 图标的位图数据
     */
    public LonAlertDialog setCancelButtonIcon(Bitmap icon) {
        mBuilder.setNegativeButtonIcon(DrawableUtils.from(mBuilder.getContext(), icon));
        return this;
    }

    /**
     * 设置取消按钮的图标
     *
     * @param filePath 图标的文件路径
     */
    public LonAlertDialog setCancelButtonIcon(String filePath) {
        mBuilder.setNegativeButtonIcon(DrawableUtils.from(mBuilder.getContext(), filePath));
        return this;
    }

    /**
     * 设置取消按钮的图标
     *
     * @param bytes 图标字节数据的数组
     */
    public LonAlertDialog setCancelButtonIcon(byte[] bytes) {
        mBuilder.setNegativeButtonIcon(DrawableUtils.from(mBuilder.getContext(), bytes));
        return this;
    }

    /**
     * 设置确认按钮的标题和单击事件回调
     *
     * @param title    标题
     * @param callback 单击事件回调，触发onButtonClick事件
     */
    public LonAlertDialog setOkButton(String title, DialogCallback callback) {
        mBuilder.setPositiveButton(title, (dialog, which) -> {
            if (callback != null) callback.onButtonClick(which);
        });
        return this;
    }

    /**
     * 设置取消按钮的标题和单击事件回调
     *
     * @param title    标题
     * @param callback 单击事件回调，触发onButtonClick事件
     */
    public LonAlertDialog setCancelButton(String title, DialogCallback callback) {
        mBuilder.setNegativeButton(title, (dialog, which) -> {
            if (callback != null) callback.onButtonClick(which);
        });
        return this;
    }

    /**
     * 设置中立按钮的标题和单击事件回调
     *
     * @param title    标题
     * @param callback 单击事件回调，触发onButtonClick事件
     */
    public LonAlertDialog setCenterButton(String title, DialogCallback callback) {
        mBuilder.setNeutralButton(title, (dialog, which) -> {
            if (callback != null) callback.onButtonClick(which);
        });
        return this;
    }

    /**
     * 设置对话框被取消显示的回调
     *
     * @param callback 事件回调，触发onCancel事件
     */
    public LonAlertDialog setOnCancel(DialogCallback callback) {
        mBuilder.setOnCancelListener(dialog -> {
            if (callback != null) callback.onCancel();
        });
        return this;
    }

    /**
     * 设置对话框被关闭的回调
     *
     * @param callback 事件回调，触发onDismiss事件
     */
    public LonAlertDialog setOnDismiss(DialogCallback callback) {
        mBuilder.setOnDismissListener(dialog -> {
            if (callback != null) callback.onDismiss();
        });
        return this;
    }

    /**
     * 显示对话框。对话框未显示之前，实际上是一个对话框的构造器，
     * 显示之后，返回一个对话框的封装对象，可以通过该对象进一步操作对话框。
     */
    public AlertDialogWrapper show() {
        return new AlertDialogWrapper(mBuilder.show());
    }

    /**
     * 创建对话框封装对象。对话框未显示之前，实际上是一个对话框的构造器，
     * 创建对话框的封装对象之后可以进一步操作对话框，比如显示对话框。
     */
    public AlertDialogWrapper create() {
        return new AlertDialogWrapper(mBuilder.create());
    }

    /**
     * 取对话框的上下文
     */
    public Context getContext() {
        return mBuilder.getContext();
    }

    public static class AlertDialogWrapper {
        private final androidx.appcompat.app.AlertDialog mDialog;
        public AlertDialogWrapper(androidx.appcompat.app.AlertDialog dialog) {
            mDialog = dialog;
        }

        /**
         * 获取原对话框对象(androidx.appcompat.app.AlertDialog)
         */
        public androidx.appcompat.app.AlertDialog getDialog() {
            return mDialog;
        }

        public Context getContext() {
            return mDialog.getContext();
        }

        /**
         * 设置对话框的图标
         * 
         * @param resId 图标资源id
         */
        public AlertDialogWrapper setIcon(int resId) {
            mDialog.setIcon(resId);
            return this;
        }

        /**
         * 设置对话框的图标
         *
         * @param icon 图标的位图数据
         */
        public AlertDialogWrapper setIcon(Bitmap icon) {
            mDialog.setIcon(DrawableUtils.from(mDialog.getContext(), icon));
            return this;
        }

        /**
         * 设置对话框的图标
         *
         * @param filePath 图标的文件路径
         */
        public AlertDialogWrapper setIcon(String filePath) {
            mDialog.setIcon(DrawableUtils.from(mDialog.getContext(), filePath));
            return this;
        }

        /**
         * 设置对话框的图标
         *
         * @param bytes 图标字节数据的数组
         */
        public AlertDialogWrapper setIcon(byte[] bytes) {
            mDialog.setIcon(DrawableUtils.from(mDialog.getContext(), bytes));
            return this;
        }

        /**
         * 设置可否取消显示对话框
         *
         * @param cancelable 为true表示可以取消，否则不能取消
         */
        public AlertDialogWrapper setCancelable(boolean cancelable) {
            mDialog.setCancelable(cancelable);
            return this;
        }

        /**
         * 设置对话框显示的信息
         *
         * @param message 信息内容
         */
        public AlertDialogWrapper setMessage(String message) {
            mDialog.setMessage(message);
            return this;
        }

        /**
         * 设置对话框显示的标题
         *
         * @param title 标题内容
         */
        public AlertDialogWrapper setTitle(String title) {
            mDialog.setTitle(title);
            return this;
        }

        /**
         * 设置对话框的自定义视图
         *
         * @param view 视图对象
         */
        public AlertDialogWrapper setView(View view) {
            mDialog.setView(view);
            return this;
        }

        /**
         * 设置对话框标题区的自定义视图
         *
         * @param view 视图对象
         */
        public AlertDialogWrapper setTitleView(View view) {
            mDialog.setCustomTitle(view);
            return this;
        }

        /**
         * 设置对话框被取消显示的回调
         *
         * @param callback 事件回调，触发onCancel事件
         */
        public AlertDialogWrapper setOnCancel(DialogCallback callback) {
            mDialog.setOnCancelListener(dialog -> {
                if (callback != null) callback.onCancel();
            });
            return this;
        }

        /**
         * 设置对话框被关闭的回调
         *
         * @param callback 事件回调，触发onDismiss事件
         */
        public AlertDialogWrapper setOnDismiss(DialogCallback callback) {
            mDialog.setOnDismissListener(dialog -> {
                if (callback != null) callback.onDismiss();
            });
            return this;
        }

        /**
         * 设置对话框内容区的自定义视图
         *
         * @param layoutResId 布局资源id
         */
        public AlertDialogWrapper setContentView(int layoutResId) {
            mDialog.setContentView(layoutResId);
            return this;
        }

        /**
         * 设置对话框内容区的自定义视图
         *
         * @param view 视图对象
         */
        public AlertDialogWrapper setContentView(View view) {
            mDialog.setContentView(view);
            return this;
        }

        /**
         * 设置确认按钮的标题和单击事件回调
         *
         * @param title    标题
         * @param callback 单击事件回调，触发onButtonClick事件
         */
        public AlertDialogWrapper setOkButton(String title, DialogCallback callback) {
            mDialog.setButton(BUTTON_OK, title, (dialog, which) -> {
                if (callback != null) callback.onButtonClick(which);
            });
            return this;
        }

        /**
         * 设置取消按钮的标题和单击事件回调
         *
         * @param title    标题
         * @param callback 单击事件回调，触发onButtonClick事件
         */
        public AlertDialogWrapper setCancelButton(String title, DialogCallback callback) {
            mDialog.setButton(BUTTON_CANCEL, title, (dialog, which) -> {
                if (callback != null) callback.onButtonClick(which);
            });
            return this;
        }

        /**
         * 设置中立按钮的标题和单击事件回调
         *
         * @param title    标题
         * @param callback 单击事件回调，触发onButtonClick事件
         */
        public AlertDialogWrapper setCenterButton(String title, DialogCallback callback) {
            mDialog.setButton(BUTTON_CENTER, title, (dialog, which) -> {
                if (callback != null) callback.onButtonClick(which);
            });
            return this;
        }

        /**
         * 显示对话框
         */
        public AlertDialogWrapper show() {
            mDialog.show();
            return this;
        }

        /**
         * 隐藏对话框，变为不可见，但未关闭，可使用show()函数重新显示
         */
        public AlertDialogWrapper hide() {
            mDialog.hide();
            return this;
        }

        /**
         * 关闭对话框
         */
        public AlertDialogWrapper dismiss() {
            mDialog.dismiss();
            return this;
        }

        /**
         * 设置对话框点击外部可否关闭
         *
         * @param cancel 可否关闭
         */
        public AlertDialogWrapper setCanceledOnTouchOutside(boolean cancel) {
            mDialog.setCanceledOnTouchOutside(cancel);
            return this;
        }

        /**
         * 判断对话框是否正在显示
         */
        public boolean isShow() {
            return mDialog.isShowing();
        }
    }

    /**
     * 对话框的接口事件
     */
    public abstract static class DialogCallback {
        /**
         * 被单击事件
         *
         * @param index 单击项目的索引
         */
        public void onItemClick(int index) {
        }

        /**
         * 多选列表被单击事件
         *
         * @param index     单击项目的索引
         * @param isChecked 是否选中
         */
        public void onMultiItemCheck(int index, boolean isChecked) {
        }

        /**
         * 按钮被单击
         *
         * @param witch 按钮id，参考常量：BUTTON_***
         */
        public void onButtonClick(int witch) {
        }

        /**
         * 对话框被取消显示
         */
        public void onCancel() {
        }

        /**
         * 对话框被关闭
         */
        public void onDismiss() {
        }
    }
}
